import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.CountDownLatch;

/**
 * TODO
 * className: ReadThread
 * package: PACKAGE_NAME
 * author: cosco
 * mail: gt.fan@msn.cn
 * create 2018-11-27 22:08
 **/

public class ReadThread extends Thread {

    /**
     * 定义字节数组的长度
     */
    private int BUFF_LEF = 256;

    /**
     * 定义读取起始点
     */
    private long start;

    /**
     * 定义读取结束点
     */
    private long end;

    /**
     * 线程需要指定的关键字
     */
    private String keywords;

    /**
     * 线程读取到关键字的次数
     */
    private int count = 0;

    /**
     * 将读取到的字节输出到raf中  randomAccessFile可以理解为文件流，即文件中提取指定的一部分的包装对象
     */
    private RandomAccessFile raf;

    /**
     * jdk1.5开始加入的类，是个多线程辅助类
     * 用于多线程开始前统一执行操作或者多线程执行完成后调用主线程执行相应操作的类
     */
    private CountDownLatch doneSignal;

    private KeyWordsCount keyWordsCount;

    public ReadThread(long start,
                      long end,
                      String keywords,
                      RandomAccessFile raf,
                      CountDownLatch doneSignal,
                      KeyWordsCount keyWordsCount
    ){
        this.start = start;
        this.end = end;
        this.keywords = keywords;
        this.raf = raf;
        this.doneSignal = doneSignal;
        this.keyWordsCount = keyWordsCount;
    }

    /**
     * 返回关键字出现的次数
     * @param result
     * @param keywords
     * @return
     */
    public int getCountByKeywords(String result, String keywords){
        return result.split(keywords).length - 1;
    }

    @Override
    public void run(){
        try {
            raf.seek(start);
            // 本次读取文件大小
            long contengLen = end - start;

            //
            long times = contengLen / BUFF_LEF + 1;
            System.out.println(this.toString() + " 需要读的次数："+times);
            byte[] buff = new byte[BUFF_LEF];
            int hadRead = 0;
            String result = null;
            int c = 0;
            for (int i = 0; i < times; i++){
                hadRead = raf.read(buff);
                if(hadRead < 0){
                    break;
                }

                result = new String(buff, "gb2312");
                c = this.getCountByKeywords(result, keywords);
                if(c > 0){
                    this.count += c;
                }
            }

            this.keyWordsCount.addCount(this.count);
            doneSignal.countDown();

        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    public int getBUFF_LEF() {
        return BUFF_LEF;
    }

    public void setBUFF_LEF(int BUFF_LEF) {
        this.BUFF_LEF = BUFF_LEF;
    }

    public long getStart() {
        return start;
    }

    public void setStart(long start) {
        this.start = start;
    }

    public long getEnd() {
        return end;
    }

    public void setEnd(long end) {
        this.end = end;
    }

    public String getKeywords() {
        return keywords;
    }

    public void setKeywords(String keywords) {
        this.keywords = keywords;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public RandomAccessFile getRaf() {
        return raf;
    }

    public void setRaf(RandomAccessFile raf) {
        this.raf = raf;
    }

    public CountDownLatch getDoneSignal() {
        return doneSignal;
    }

    public void setDoneSignal(CountDownLatch doneSignal) {
        this.doneSignal = doneSignal;
    }

    public KeyWordsCount getKeyWordsCount() {
        return keyWordsCount;
    }

    public void setKeyWordsCount(KeyWordsCount keyWordsCount) {
        this.keyWordsCount = keyWordsCount;
    }
}
